1. Technical Field
The present invention relates in general to improved heap management and in particular to improved efficiency of heap management by a virtual manager in a multiprocessor system. Still more particularly, the present invention relates to improved free item distribution among multiple free lists during garbage collection to improve memory usage and to increase the frequency of allocations from thread-local heaps.
2. Description of the Related Art
Software systems, such as the Java Virtual Machine (JVM) that employ garbage collection, typically provide an explicit call for allocating objects, but no explicit call for freeing objects. Instead, in a system that employs garbage collection, when available storage on a heap is exhausted, an allocation failure occurs, operations are suspended, and garbage collection is invoked to replenish the free storage.
In one example, the JVM employs a mark and sweep phases during garbage collection to replenish the free storage. During a mark phase, items that are still referenced are located and marked. Then, during the sweep phase, free space of sufficient size is located and added as free items to a free list. Free items that are not large enough to be added to the free list are discarded. A free list may include a linked list of freed items, for example, with a pointer to the first item in the list held in global memory.
In addition, during garbage collection, compaction may occur. Compaction, in general, requires adjusting the position of objects within the heap to reduce fragmentation and attempt to make larger free items available. A forced compaction may occur if the sweep phase completes without finding a sufficiently large free item for the allocation request.
When an allocation request is received, a heap lock is acquired and the free list is scanned to locate a free item of sufficient size to meet the allocation request. If a free item of sufficient size is available on the list, it is popped from the list so that the new object can be allocated at the free item location. If a free item of sufficient size is not available, then garbage collection is initiated again to replenish the free list.
Because the heap lock is an exclusive lock and is acquired to search a free list, it is important that free items are efficiently located and popped from the list during allocation and, in particular, that the free list can be efficiently scanned to determine if a free item is available. In addition, because garbage collection is time consuming, it is important that larger items are not prematurely popped from the free list such that premature garbage collection is initiated. In particular, a premature garbage collection may occur if an allocation failure occurs and there is a large amount of free storage available, but no single free item large enough to satisfy the allocation request.
In an attempt to reduce the chance of premature garbage collection and reduce free list scanning time, some JVM's implement a large object area (LOA) or other large object protection area within the heap, where the LOA includes objects that are greater than a large object size threshold. Objects within the LOA are typically not allocated unless the requested allocation size is larger than the large object size threshold in an attempt to reduce premature garbage collection when large object requests are received.
In addition, in an attempt to increase the efficiency of searching for a free item, some JVM's implement multiple free lists, where each free list holds free items of a particular size. A vector maintains the list of sizes, wherein the list of sizes is scanned to locate a particular sized free list and then that sized free list is scanned for a free item of sufficient size for the allocation request, rather than requiring a scan of each item of a free list. While multiple free lists organized by a searchable vector reduce the number of free items that must be searched, searching a free list requires acquiring a heap lock.
Further, in an attempt to increase the efficiency of allocations of smaller objects, thread-local heaps (TLHs) may be implemented. In one example, a TLH is a cache buffer that has been previously reserved for use by a single thread. TLHs are advantageous because objects can be allocated directly to a TLH without the thread grabbing a heap lock. Furthermore, TLH's typically employ simple and fast allocation schemes, such as pointer bumping. Thus, it is advantageous to allocate as often as possible from the TLH, rather than searching from general free lists.
While allocating from a TLH is most efficient for smaller objects, when the current TLH does not have sufficient space to satisfy an allocation request, but the allocation request is within the size boundaries of a TLH, the heap lock must still be acquired to search the free list for a free item of sufficient size. The current TLH is replaced by a free item popped from a general free list. In addition, if an allocation request size exceeds the size boundaries of a TLH, the heap lock must still be acquired and the free lists must be searched to find a free item large enough to satisfy the request size. Thus, while implementing TLHs may improve efficiency of allocations when the requested allocation fits within the current TLH, current object allocation is still limited when the current TLH does not satisfy the allocation request.
Another issue arises in TLH allocation because the majority of requests for free items from the heap manager become requests for TLH replenishments. As a result, the free lists with smaller free items that are also large enough for TLH allocation will quickly be depleted, leading to premature garbage collection as larger items are carved up to meet normal smaller object allocation requests. One solution to the smaller free item depletion problem has been to increase the size of TLH's, however merely increasing the size only adjusts the low value of the range of free list sizes that are most quickly depleted by TLH requests, still leading to premature garbage collection when other allocation requests within the TLH size range are received.
Therefore, in view of the foregoing, there is a need for a method, system, and program for improving free item distribution among free lists to avoid premature depletion from TLH requests by using recent allocation history to predict future allocation requirements and distributing free items among free lists to meet the predicted future allocation requirements. In addition, to increase the efficiency of object allocation, there is a need for a method, system, and program for avoiding the acquisition of heap lock and in particular avoiding the acquisition of heap lock during TLH replenishment.